package NG::Gen::Users::Secure;
use strict;
use warnings;
use utf8;

use Digest::MD5 qw(md5_hex);
use Time::HiRes qw(gettimeofday);
use NG::Sys::Datetime;
use NG::Sys::Text;

sub do_user_login {
	my ($self,$ip) = @_;
	if($self->online){
		$self->close_session($self->session_start,$self->checked);
	}
	my $key = md5_hex(scalar gettimeofday(),rand());
	my $now = unixtime2timestamp();
	$self->update_data(
					session => $key,
					vk => (111111+int rand(88888)),
					session_ip => $ip,
					session_start => $now,
					chat_pass => (11111111+int rand(8888888)),
				);
	$self->replace_data(
					online_title => $self->title,
					online => 1,
					checked => $now,
				);
	$self->after_login;
	return $key;
}
sub check_session {
	my ($self,$session) = @_;
	my $vs;
	return $session && ($vs = $self->session) && $vs eq $session;
}
sub check_online {
	my ($self) = @_;
	$self->update_data(online => 1,checked => unixtime2timestamp());
}
sub crypt_password {
	my ($pass) = @_;
	my $key = md5_hex(scalar gettimeofday(),rand());
	return crypt $pass,$key;
}
sub check_password {
	my ($self,$pass) = @_;
	my $crypted;
	unless($crypted = $self->password){
		return 0;
	}
	return $crypted eq crypt $pass,$crypted;
}
sub do_user_logout {
	my ($self) = @_;
	my $now = unixtime2timestamp();
	$self->update_data(session => undef, online => 0, checked => $now);
	my $ret = $self->close_session($self->session_start,$now);
	$self->after_logout;
	return $ret;
}
sub close_session {
	my ($self,$start,$end) = @_;
	unless($start and $end){
		return;
	}
	my $t_start = timestamp2unixtime($start);
	my $t_end = timestamp2unixtime($end);
	unless($t_start and $t_end){
		return;
	}
	$self->{parent}{dbh}->Insert(user_sessions => {
		user_id => $self->{id},
		start => $start,
		end => $end,
		ip => $self->session_ip,
		duration => $t_end - $t_start,
		v => ($self->validate ? 1 : 0),
		});
}
sub validate_user {
	my ($self,$login,$pass) = @_;
	if(my $err = check_login_valid($login)){
		return $err;
	}
	if(my $err = check_password_valid($pass)){
		return $err;
	}
	if($self->{parent}->check_login($login)){
		return "Логин '$login', не доступен";
	}
	$pass = crypt_password($pass);
	my $now = unixtime2timestamp();
	my $old_login = $self->login;
	my %data = (
			password => $pass, pass_changed => $now,
			login => $login, login_changed => $now,
			title => $login,
			validate => $now,
			online_title => $login,
		);
	$self->update_data(\%data);
	$self->after_validate($old_login);
	return undef;
}

1;
